package com.craftworks.tiles.impl;

import cn.hutool.core.util.StrUtil;
import com.craftworks.tiles.AbstractTile;
import org.kordamp.ikonli.coreui.CoreUiFree;
import org.kordamp.ikonli.swing.FontIcon;

import javax.swing.*;
import java.awt.*;
import java.util.List;

public class NetTrafficTile extends AbstractTile
{
    private String port;
    private long inRate;
    private long outRate;
    private FontMetrics fmPort;
    private FontMetrics fmRate;

    private static final Color BACKGROUND = Color.decode("#18181A");
    private static final Font FONT_PORT = new Font("Inter Variable Text Light", Font.PLAIN, 24);
    private static final Font FONT_RATE = new Font("Source Han Sans CN", Font.PLAIN, 16);
    private static final Icon ICON_IN = FontIcon.of(CoreUiFree.DATA_TRANSFER_DOWN, 16, Color.decode("#ffa600"));
    private static final Icon ICON_OUT = FontIcon.of(CoreUiFree.DATA_TRANSFER_UP, 16, Color.decode("#eeff00"));

    public NetTrafficTile()
    {
        super(Size.WIDE_LANDSCAPE);
    }

    @Override
    public List<String> propertyKeys()
    {
        return List.of("port", "in.bitrate", "out.bitrate");
    }

    @Override
    public void setProperty(String key, Object value)
    {
        switch (key)
        {
            case "port" ->
            {
                switch (value)
                {
                    case null -> port = "---";
                    case String s -> port = s;
                    default -> throw new IllegalStateException("Unexpected value: " + value);
                }
                repaint();
            }
            case "in.bitrate" ->
            {
                switch (value)
                {
                    case null -> inRate = -1;
                    case String s -> inRate = Long.parseLong(s);
                    case Number n -> inRate = n.longValue();
                    default -> throw new IllegalStateException("Unexpected value: " + value);
                }
                repaint();
            }
            case "out.bitrate" ->
            {
                switch (value)
                {
                    case null -> outRate = -1;
                    case String s -> outRate = Long.parseLong(s);
                    case Number n -> outRate = n.longValue();
                    default -> throw new IllegalStateException("Unexpected value: " + value);
                }
                repaint();
            }
        }
    }

    private String normalize(long value)
    {
        if (value < 0)
            return "---";
        if (value >= 1000_000_000_000_000L)
            return "---";
        if (value >= 1000_000_000_000L)
            return String.format("%.1f Tbps", value / 1000000000000.0d);
        if (value >= 1000_000_000)
            return String.format("%.1f Gbps", value / 1000000000.0d);
        if (value >= 1000_000)
            return String.format("%.1f Mbps", value / 1000000.0d);
        if (value >= 1000)
            return String.format("%.1f Kbps", value / 1000.0d);
        return String.format("%d bps", value);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        g2d.setPaint(BACKGROUND);
        g2d.fillRect(0, 8, size.width, 42);

        if (fmPort == null)
            fmPort = g2d.getFontMetrics(FONT_PORT);
        if (fmRate == null)
            fmRate = g2d.getFontMetrics(FONT_RATE);

        port = StrUtil.nullToDefault(port, "---");
        int width = fmPort.stringWidth(port);
        g2d.setFont(FONT_PORT);
        g2d.setPaint(FOREGROUND);
        g2d.drawString(port, (size.width - width) / 2, 38);

        ICON_IN.paintIcon(this, g2d, 10, 56);
        ICON_OUT.paintIcon(this, g2d, 10, 75);

        String inRateStr = normalize(inRate);
        width = fmRate.stringWidth(inRateStr);
        g2d.setFont(FONT_RATE);
        g2d.setPaint(FOREGROUND);
        g2d.drawString(inRateStr, 124 - width, 70);

        String outRateStr = normalize(outRate);
        width = fmRate.stringWidth(outRateStr);
        g2d.drawString(outRateStr, 124 - width, 90);
    }
}
